package ch.fhnw.qualiscan.core.db.fieldfactories;

import ch.fhnw.qualiscan.application.models.QuestionnaireModel;
import ch.fhnw.qualiscan.core.db.HibernateSession;
import ch.fhnw.qualiscan.core.db.pojos.Category;
import ch.fhnw.qualiscan.core.db.pojos.Domain;
import ch.fhnw.qualiscan.core.db.pojos.DomainText;
import ch.fhnw.qualiscan.core.db.pojos.Questionnaire;
import ch.fhnw.qualiscan.core.db.pojos.University;
import ch.fhnw.qualiscan.core.helpers.UserSession;
import ch.fhnw.qualiscan.core.helpers.UserSessionHelper;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.FormFieldFactory;
import com.vaadin.ui.PopupDateField;
import com.vaadin.ui.TextField;
import com.vaadin.ui.TwinColSelect;
import eu.livotov.tpt.i18n.TM;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
 * Creates the Fields for Survey pojos in forms.
 * @author Kevin Mettenberger
 *
 */
@SuppressWarnings("serial")
public class SurveyFieldFactory implements FormFieldFactory {
	
	public HibernateSession hs;
        public TwinColSelect domains = new TwinColSelect(TM.get("survey.domain"));
        public QuestionnaireModel qModel;
        public SurveyFieldFactory thisClass;
        UserSession user;
        UserSessionHelper sessionHelper;
        Questionnaire questionnaire;

        public SurveyFieldFactory(Questionnaire questionnaire) {
            this.questionnaire = questionnaire;
            hs = new HibernateSession();
            qModel = new QuestionnaireModel();
            sessionHelper = new UserSessionHelper();
            user = sessionHelper.getUserSession();
        }
	
     
    public Field createField(Item item, Object propertyId, Component uiContext) {
		String pid = (String) propertyId;
		
		if (pid.equals("title")) {
			TextField title = new TextField(TM.get("survey.title"));
			title.setRequired(true);
			title.setWidth("300px");
			title.setRequiredError(TM.get("survey.error.title"));
            return title;
        } else if (pid.equals("domains")) {
                domains.setImmediate(true);
             
                final BeanItemContainer<Integer> cont = new BeanItemContainer<Integer> (Integer.class);
                Set<Domain> ds = questionnaire.getDomains();

                for(Domain d : ds) {
                    cont.addItem(d.getId());
                }

                domains.setContainerDataSource(cont);

                for (int i = 0; i < cont.size(); i++) {
                    Domain d = new Domain();
                    d.setId(cont.getIdByIndex(i));

                    DomainText dt = (DomainText) hs.getSession().createQuery("from DomainText as dt where dt.domain = :domain AND dt.language = :language")
                        .setParameter("domain", d)
                        .setParameter("language", user.getLanguage())
                        .uniqueResult();

                    domains.setItemCaption(d.getId(), dt.getText());

                }

                domains.setRequired(true);
                domains.setRequiredError(TM.get("survey.error.domain"));

    		
            return domains;
        }else if(pid.equals("completiondate")) {
        	
        	PopupDateField completionDate = new PopupDateField(TM.get("survey.completion"));
        	completionDate.setResolution(PopupDateField.RESOLUTION_DAY);
        	completionDate.setDateFormat("dd.MM.yyyy");
        	completionDate.setImmediate(true);
        	completionDate.addListener(new Property.ValueChangeListener() {
				public void valueChange(ValueChangeEvent event) {
					if (event.getProperty().getValue() != null) {
						Date now = new Date();
						if (now.compareTo((Date) event.getProperty().getValue()) < 0) {
							
						} else {
							event.getProperty().setValue(null);
						}
					}
				}
			});
        	completionDate.setRequired(true);
        	completionDate.setRequiredError(TM.get("survey.error.completion"));
        	
        	return completionDate;
        	
        }else if(pid.equals("category")) {
        	//Needs to be converted into a bean item, because the form is using a beantitem as its data source
        	List<Category> lc = hs.getSession().createCriteria(Category.class).list();
        	BeanItemContainer<Category> bic = new BeanItemContainer<Category>(Category.class);
        	
        	for(int i = 0; i < lc.size();i++) {
        		bic.addBean(lc.get(i));
        	}
        	
        	ComboBox category = new ComboBox(TM.get("survey.category"));
        	category.setContainerDataSource(bic);
        	category.setImmediate(true);
        	category.setItemCaptionPropertyId("title");
        	category.setRequired(true);
        	category.setRequiredError(TM.get("survey.error.category"));
        	
        	return category;
        }
        else if(pid.equals("university")) {
        	List<University> lc = hs.getSession().createCriteria(University.class).list();
        	BeanItemContainer<University> bic = new BeanItemContainer<University>(University.class);
        	
        	for(int i = 0; i < lc.size();i++) {
        		bic.addBean(lc.get(i));
        	}
        	
        	ComboBox university = new ComboBox(TM.get("survey.university"));
        	university.setContainerDataSource(bic);
        	university.setImmediate(true);
        	university.setItemCaptionPropertyId("title");
        	university.setRequired(true);
        	university.setRequiredError(TM.get("survey.error.university"));
        	
        	return university;
        } else {
            return DefaultFieldFactory.get().createField(item, propertyId, uiContext);
        }

    }

    private void updateDomains(Property property) {
        domains.setEnabled(true);
        
        Questionnaire questionnaire = (Questionnaire) property.getValue();
                
        final BeanItemContainer<Integer> cont = new BeanItemContainer<Integer> (Integer.class);
        Set<Domain> ds = questionnaire.getDomains();
        
        for(Domain d : ds) {
            cont.addItem(d.getId());
        }
        
        domains.setContainerDataSource(cont);
        
        for (int i = 0; i < cont.size(); i++) {
            Domain d = new Domain();
            d.setId(cont.getIdByIndex(i));
            
            DomainText dt = (DomainText) hs.getSession().createQuery("from DomainText as dt where dt.domain = :domain AND dt.language = :language")
                .setParameter("domain", d)
                .setParameter("language", user.getLanguage())
                .uniqueResult();
            
            domains.setItemCaption(d.getId(), dt.getText());
            
        }
        
        domains.setRequired(true);
    	domains.setRequiredError(TM.get("survey.error.domain"));
        
    }
}
